﻿/*************************************************************************
 *  Matrix library créer par Zaghdoudi Taha 02/01/2012
 *  Le contenu de cette librairie est FREE donc vous pouvez le changer 
 *  Enjoy programming with Taha 
 *  Vector A = new Vector(double[] data);
 *
 *************************************************************************/
using System;

namespace TMatrix
{
	/// <summary>
	/// Description of Vector.
	/// </summary>
	public class Vector
	{
		private int n;
		private double[] data;
		public Vector(int n)
		{
			this.n=n;
			this.data= new double[n];
			for(int i=0;i<n;i++){
				this.data[i]=0.0;
			}
		}
		public Vector(double[] data){
			this.n = data.Length;
			this.data=data;
		}
		public double this[int i]{
			get{
				if (i < 0 || i > n){
					throw new Exception("Requested vector index is out of range!");
				}
				return data[i];
			}
			set{
				data[i]=value;
			}
		}
		public int Vsize{
			get{
				return n;
			}
		}
		public Vector Clone(){
			Vector v = new Vector(data);
			v.data= (double[])data.Clone();
			return v;
		}
		public static Vector operator +(Vector a){
			return a;
		}
		public static Vector operator +(Vector a, Vector b){
			Vector c = new Vector(a.Vsize);
			for(int i=0;i<c.Vsize;i++){
				c[i]= a[i]+b[i];
			}
			return c;
		}
		public static Vector operator -(Vector a){
			double[] c = new double[a.Vsize];
			for(int i=0;i<c.Length;i++){
				c[i]=-a[i];
			}
			return new Vector(c);
		}
		public static Vector operator -(Vector a, Vector b){
			Vector c = new Vector(a.Vsize);
			for(int i=0;i<c.Vsize;i++){
				c[i]= a[i]-b[i];
			}
			return c;
		}
		public static Vector operator *(Vector a, double d){
			Vector c = new Vector(a.Vsize);
			for(int i=0;i<c.Vsize;i++){
				c[i]= a[i]*d;
			}
			return c;
		}
		public static Vector operator *( double d, Vector a){
			Vector c = new Vector(a.Vsize);
			for(int i=0;i<c.Vsize;i++){
				c[i]= a[i]*d;
			}
			return c;
		}
		public static Vector operator /(Vector a, double d){
			Vector c = new Vector(a.Vsize);
			for(int i=0;i<c.Vsize;i++){
				c[i]= a[i]/d;
			}
			return c;
		}
		public static Vector operator /(double d, Vector a){
			Vector c = new Vector(a.Vsize);
			for(int i=0;i<c.Vsize;i++){
				c[i]= a[i]/d;
			}
			return c;
		}
		public static double Dotproduct(Vector a , Vector b){
			double c =0.0;
			for(int i=0;i<a.Vsize;i++){
				c= a[i]*b[i];
			}
			return c;
		}
		
		public double getNorm(){
			double c =0.0;
			for(int i=0;i<n;i++){
				c += data[i]*data[i];
			}
			return Math.Sqrt(c);
		}
		public double getNormSquare(){
			double c =0.0;
			for(int i=0;i<n;i++){
				c += data[i]*data[i];
			}
			return c;
		}
		public void Normlize(){
			double norm = getNorm();
			if(norm==0){
				throw new Exception("Tried to normalize a vector with norm of zero!");
			}
			for (int i = 0; i<n; i++){
				data[i]/=norm;
			}
		}
		public static Vector CrossProduct(Vector a, Vector b){
			if (a.Vsize != 3){
				throw new Exception("Vector a must be 3 dimensional!");
			}
			if (b.Vsize != 3){
				throw new Exception("Vector b must be 3 dimensional!");
			}
			Vector c = new Vector(3);
			c[0] = a[1] * b[2] - a[2] * b[1];
			c[1] = a[2] * b[0] - a[0] * b[2];
			c[2] = a[0] * b[1] - a[1] * b[0];
			return c;
		}
	}
}
